"""
数据处理模块
负责数据处理、文件操作和绘图协调
"""

import os
import shutil
import matplotlib.pyplot as plt
from utils.file_handler import FileHandler
from core.plot_manager import PlotManager


class DataProcessor:
    """数据处理类，负责协调文件处理和绘图"""
    
    def __init__(self):
        self.file_handler = FileHandler()
        self.plot_manager = PlotManager()
    
    def process_preview_request(self, filepaths):
        """
        处理预览请求
        
        Args:
            filepaths: 文件路径列表
            
        Returns:
            str: 预览文本，如果失败返回错误信息
        """
        if not filepaths:
            return "没有选择文件"
        
        try:
            file_params = self.file_handler.read_file_parameters(filepaths[0])
            return self.file_handler.create_preview_text(file_params)
        except Exception as e:
            return f"无法预览文件: {str(e)}"
    
    def process_files_loaded(self, filepaths):
        """
        处理文件加载完成事件
        
        Args:
            filepaths: 文件路径列表
            
        Returns:
            dict: 包含采样频率和时间结束值的字典
        """
        if not filepaths:
            return {}
        
        try:
            file_params = self.file_handler.read_file_parameters(filepaths[0])
            if file_params:
                return {
                    'fs_mhz': file_params['fs_mhz'],
                    't_max_us': file_params['t_max_us']
                }
        except Exception as e:
            print(f"Error processing loaded files: {e}")
        
        return {}
    
    def process_plot_request(self, parameters):
        """
        处理绘图请求
        
        Args:
            parameters: 绘图参数字典
            
        Returns:
            dict: 处理结果，包含成功状态和消息
        """
        try:
            filepaths = parameters['filepaths']
            channels_to_plot = parameters['channels_to_plot']
            plot_or_save = parameters['plot_or_save']
            single_multi = parameters['single_multi']
            
            if single_multi == 'single':
                return self._process_single_plot_mode(filepaths, channels_to_plot, plot_or_save, parameters)
            else:
                return self._process_multi_plot_mode(filepaths, channels_to_plot, plot_or_save, parameters)
                
        except Exception as e:
            return {
                'success': False,
                'message': f"绘图处理出错: {str(e)}"
            }
    
    def _process_single_plot_mode(self, filepaths, channels_to_plot, plot_or_save, parameters):
        """
        处理单图模式
        
        Args:
            filepaths: 文件路径列表
            channels_to_plot: 要绘制的通道列表
            plot_or_save: 绘图或保存模式
            parameters: 绘图参数
            
        Returns:
            dict: 处理结果
        """
        new_filepaths = list(filepaths)
        processed_count = 0
        
        for i, file_path in enumerate(filepaths):
            # 获取文件数据
            t, ADCs, ADCsorg, params, smplfreq, CMname = self.file_handler.get_file_data(file_path)
            if t is None:
                continue
            
            # 创建图形
            npR, npC = self.plot_manager.get_plot_grid_size(len(channels_to_plot))
            fig, axes = plt.subplots(
                npR, npC, 
                figsize=parameters['figure_size'],
                squeeze=False
            )
            
            # 绘制内容
            self.plot_manager.plot_figure_content(
                axes, channels_to_plot, t, ADCs, ADCsorg, smplfreq, 
                params, CMname, parameters
            )
            
            # 设置标题
            header = self.file_handler.create_header(params, CMname)
            self.plot_manager.setup_figure_layout(fig, header)
            
            if plot_or_save == 'Plot':
                plt.show()
            else:  # Save
                result = self._save_and_move_file(file_path, fig, ADCsorg, parameters)
                if result['success']:
                    new_filepaths[i] = result['new_path']
                    processed_count += 1
                else:
                    plt.close(fig)
                    return result
        
        if plot_or_save == 'Save':
            return {
                'success': True,
                'message': f"{processed_count} 个文件处理完成并保存",
                'new_filepaths': new_filepaths
            }
        else:
            return {
                'success': True,
                'message': f"{processed_count} 个文件绘制完成"
            }
    
    def _process_multi_plot_mode(self, filepaths, channels_to_plot, plot_or_save, parameters):
        """
        处理多图模式
        
        Args:
            filepaths: 文件路径列表
            channels_to_plot: 要绘制的通道列表
            plot_or_save: 绘图或保存模式
            parameters: 绘图参数
            
        Returns:
            dict: 处理结果
        """
        new_filepaths = list(filepaths)
        
        # 创建图形
        npR, npC = self.plot_manager.get_plot_grid_size(len(channels_to_plot))
        fig, axes = plt.subplots(
            npR, npC, 
            figsize=parameters['figure_size'],
            squeeze=False
        )
        
        final_header = ""
        final_png_path = ""
        
        try:
            for i, file_path in enumerate(filepaths):
                # 获取文件数据
                t, ADCs, ADCsorg, params, smplfreq, CMname = self.file_handler.get_file_data(file_path)
                if t is None:
                    continue
                
                # 绘制内容（带有多图图例）
                self.plot_manager.plot_figure_content(
                    axes, channels_to_plot, t, ADCs, ADCsorg, smplfreq, 
                    params, CMname, parameters, multi_plot_legend=CMname
                )
                
                final_header = self.file_handler.create_header(params, CMname)
                
                if plot_or_save == 'Save':
                    result = self._save_and_move_file(file_path, None, ADCsorg, parameters)
                    if result['success']:
                        new_filepaths[i] = result['new_path']
                        final_png_path = result['png_path']
                    else:
                        plt.close(fig)
                        return result
            
            # 设置图形布局
            self.plot_manager.setup_figure_layout(fig, final_header)
            self.plot_manager.consolidate_legend(fig)
            
            if plot_or_save == 'Plot':
                plt.show()
                return {
                    'success': True,
                    'message': "多图绘制完成"
                }
            else:  # Save
                if final_png_path:
                    try:
                        fig.savefig(final_png_path)
                        plt.close(fig)
                        return {
                            'success': True,
                            'message': f"复合图保存到 {final_png_path}，{len(filepaths)} 个文件已移动",
                            'new_filepaths': new_filepaths
                        }
                    except Exception as e:
                        plt.close(fig)
                        return {
                            'success': False,
                            'message': f"无法保存最终图形: {str(e)}"
                        }
                else:
                    plt.close(fig)
                    return {
                        'success': False,
                        'message': "无法确定保存路径"
                    }
                    
        except Exception as e:
            if 'fig' in locals():
                plt.close(fig)
            return {
                'success': False,
                'message': f"多图处理出错: {str(e)}"
            }
    
    def _save_and_move_file(self, file_path, fig, ADCsorg, parameters):
        """
        保存图形并移动文件
        
        Args:
            file_path: 文件路径
            fig: matplotlib图形对象（可为None）
            ADCsorg: 原始ADC复数数据
            parameters: 参数字典
            
        Returns:
            dict: 操作结果
        """
        try:
            # 检查虚假信号
            spurious_flag = False
            if parameters['spurious_mode'] == 'off':
                spurious_flag = self.file_handler.check_spurious(ADCsorg)
            
            # 构建目标路径
            datapath, filename = os.path.split(file_path)
            fname, _ = os.path.splitext(filename)
            
            # 从文件名提取模块名
            import re
            match = re.search(r'(CM\d-\d)', filename)
            modulename = match.group(1)[:-2] if match and len(match.group(1)) > 2 else "Unknown"
            
            target_dir = os.path.join(datapath, modulename)
            if spurious_flag:
                target_dir = os.path.join(target_dir, "spurious")
            
            os.makedirs(target_dir, exist_ok=True)
            
            png_path = os.path.join(target_dir, f"{fname}.png")
            new_csv_path = os.path.join(target_dir, filename)
            
            # 保存图形（如果提供了）
            if fig is not None:
                fig.savefig(png_path)
                plt.close(fig)
            
            # 移动文件
            shutil.move(file_path, new_csv_path)
            
            return {
                'success': True,
                'new_path': new_csv_path,
                'png_path': png_path
            }
            
        except Exception as e:
            return {
                'success': False,
                'message': f"保存/移动文件失败 {os.path.basename(file_path)}: {str(e)}"
            } 